///////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
#include <Scene/SceneManager.h>
#include <Scene/Camera/Camera.h>
#include <Scene/IObjectLoader.h>
#include <File/LocalFile.h>
#include <Model/MeshManager.h>
#include <Scene/Culling/Culler.h>
#include <Scene/Object.h>
#include <Scene/Culling/FrustumCuller.h>
#include <Application.h>
#include <Shader/ShaderManager.h>
#include <tinyxml.h>
#include <Profiling/ProfilingManager.h>

//-----------------------------------------------------------------------------

SceneManager::SceneManager()
{
	m_rootNode = MGL_NEW Object();
	m_rootNode->SetSceneManager( this );
	m_culler = MGL_NEW FrustumCuller();
	m_camera = MGL_NEW Camera();
}

//-----------------------------------------------------------------------------

SceneManager::~SceneManager()
{
	SAFE_DEL( m_culler );
}

//-----------------------------------------------------------------------------

void		SceneManager::UpdateScene(f32 dt)
{
	MGL_PROFILE("SceneManager::Update");
	if( m_camera )
	{
		m_camera->Update( dt );
	}
	
	m_rootNode->Update( dt );
}

//-----------------------------------------------------------------------------

void		SceneManager::DrawScene()
{
	MGL_PROFILE("SceneManager::DrawScene");
	m_culler->Update( this );
	m_rootNode->Draw();
}

//-----------------------------------------------------------------------------

void		SceneManager::SetCamera(Camera* camera)
{
	m_camera = camera;
	if( m_camera )
	{
		m_camera->SetViewportSize( Application::GetInstance()->GetResolutionWidth(), Application::GetInstance()->GetResolutionHeight() );
	}
}

//-----------------------------------------------------------------------------

Camera*		SceneManager::GetCamera()
{
	return m_camera;
}

//-----------------------------------------------------------------------------

Object*		SceneManager::GetRootNode()
{
	return m_rootNode;
}

//-----------------------------------------------------------------------------

//Object*		SceneManager::LoadObject(std::string filename)
//{
//	if( MeshManager::GetInstance()->IsMeshLoaded( filename ) )
//	{
//		Object* obj = MGL_NEW Object();
//		Mesh* m = MeshManager::GetInstance()->GetMesh( filename );
//		obj->AddMesh( m );
//		return obj;
//	}
//	else
//	{
//		LocalFile *file = MGL_NEW LocalFile( filename.c_str() );
//		IObjectLoader *loader = IObjectLoader::GetLoaderForFile( file );
//		Object* obj = loader->LoadObject( file );
//		SAFE_DEL( file );
//		return obj;
//	}
//	return NULL;
//}

//-----------------------------------------------------------------------------

Culler*		SceneManager::GetCuller()
{
	return m_culler;
}

//-----------------------------------------------------------------------------

void		SceneManager::SetCuller(Culler*	culler)
{
	if( m_culler )
	{
		SAFE_DEL( m_culler );
	}
	m_culler = culler;
}

//-----------------------------------------------------------------------------

void		SceneManager::LoadScene(std::string filename)
{
	TiXmlDocument doc( filename.c_str() );
	if( doc.LoadFile() )
	{
		TiXmlElement* root = doc.FirstChildElement( "root" );
		if( root )
		{
			TiXmlElement* shaders = root->FirstChildElement( "shaders" );
			if( shaders )
			{
				ShaderManager::GetInstance()->ParseElement( shaders );
			}
			else
			{
				DEBUG_ERR( "[SceneManager::LoadScene] Could not find 'shaders' in '%s'!", filename.c_str() );
			}

			TiXmlElement* scene = root->FirstChildElement( "scene" );
			if( scene )
			{
				m_rootNode->ParseElement( scene );
			}
			else
			{
				DEBUG_ERR( "[SceneManager::LoadScene] Could not find 'scene' in '%s'!", filename.c_str() );
			}
		}
		else
		{
			DEBUG_ERR( "[SceneManager::LoadScene] Could not find 'root' in '%s'!", filename.c_str() );
		}
	}
	else
	{
		DEBUG_ERR( "[SceneManager::LoadScene] Could not open '%s'!", filename.c_str() );
	}
}

//-----------------------------------------------------------------------------
///////////////////////////////////////////////////////////////////////////////
